package com.versa.artflowlib;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Process;
import android.util.Log;

import com.versa.lib.Versa;
import com.versa.lib.VersaBuilder;
import com.versa.lib.listeners.CompletionListener;
import com.versa.lib.listeners.ImageSavedListener;
import com.versa.lib.listeners.OnStylizeCompletedListener;
import com.versa.lib.listeners.ProgressListener;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Created by huyaonan on 17/3/15.
 */
public class StylizeService extends Service {

    private static final String TAG = "StylizeService";

    public class StylizeBinder extends Binder {

        public StylizeService getService() {
            return StylizeService.this;
        }

    }

    private static final int CODE_IMG_SAVED = 0Xaaaaa1;
    private static final int CODE_COMPLETE = 0Xaaaaa2;

    private AtomicBoolean mStyleRunning = new AtomicBoolean(false);
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case CODE_COMPLETE:
                    break;
                case CODE_IMG_SAVED:
                    String path = (String) msg.obj;
                    sendCallback(path);
                    break;
            }
        }
    };

    private BlockingQueue<Integer> mQueue;
    private WorkingThread mWorkingThread;
    private ImageSavedListener mListener;

    public void init() {
        if(mStyleRunning.get())
            return;
        mStyleRunning.set(true);
        mQueue = new PriorityBlockingQueue<>();
        mWorkingThread = new WorkingThread();
        mWorkingThread.start();

        mQueue.add(TASK_INIT);
    }

    public void registeCallback(ImageSavedListener listener) {
        mListener = listener;
    }

    private void sendCallback(String path) {
        if(mListener != null)
            mListener.onImageSaved(path);
    }

    private static final int TASK_INIT = 1;
    private static final int TASK_STYLIZE = 2;
    private static final int TASK_DESTROY = 3;

    private class WorkingThread extends Thread {

        private Versa mVersa;

        private void quit() {
//            interrupt();
            mStyleRunning.set(false);
            if(mVersa != null) {
                mVersa.destroyArcade();
                mVersa = null;
            }
        }

        @Override
        public void run() {
            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
            int request;
            while (true) {
                try {
                    // Take a request from the queue.
                    request = mQueue.take();
                } catch (InterruptedException e) {
                    // We may have been interrupted because it was time to quit.
                    if (!mStyleRunning.get()) {
                        return;
                    }
                    continue;
                }

                try {
                    switch (request) {
                        case TASK_INIT:
                            if (mVersa == null) {
                                initVersa();
                            }
                            break;
                        case TASK_STYLIZE:
                            if (mVersa != null)
                                stylize(1);
                            break;
                        case TASK_DESTROY:
                            quit();
                            break;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        private void initVersa() {
            VersaBuilder builder = new VersaBuilder(StylizeService.this);
            mVersa = builder.build();
            mVersa.initialize();
            mVersa.setLogEnabled(true);
            mVersa.setProgressListener(new ProgressListener() {
                @Override
                public void onUpdateProgress(final String log, boolean important) {
                    Log.d(TAG, "onUpdateProgress");
                }
            });
            mVersa.setImageSavedListener(new ImageSavedListener() {
                @Override
                public void onImageSaved(String path) {
                    Log.d(TAG, "onImageSaved");
                    Message message = mHandler.obtainMessage();
                    message.what = CODE_IMG_SAVED;
                    message.obj = path;
                    mHandler.sendMessage(message);
                }
            });
            mVersa.setCompletionListsner(new CompletionListener() {
                @Override
                public void onComplete() {
                    Log.d(TAG, "onComplete");
                    mHandler.sendEmptyMessage(CODE_COMPLETE);
                }
            });
            mVersa.setOnStylizeCompletedListener(new OnStylizeCompletedListener() {
                @Override
                public void onStylizeCompleted(String originPath) {
                    Log.d(TAG, "onComplete:" + originPath);
                }
            });
            mVersa.preload();
        }

        private void stylize(int index) {
            mVersa.stylize(index);
        }

    }

    public void stylize() {
        mQueue.add(TASK_STYLIZE);
    }

    public void destroyVersa() {
        mQueue.clear();
        mQueue.add(TASK_DESTROY);
    }

    @Override
    public IBinder onBind(Intent intent) {
        return new StylizeBinder();
    }

    @Override
    public void onRebind(Intent intent) {
        super.onRebind(intent);
    }

    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}
